package CompareScheme;

/**
 * @Classname paper2
 * @Description
[15]	Zhong Y C J .
Multi-authority attribute-based encryption access control scheme with policy hidden for cloud storage[J].
Soft computing: A fusion of foundations, methodologies and applications, 2018, 22(1)
 * @Created by kevin
 */

import accessstruct.Tool;
import accessstruct.parser.ParserUtils;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;

import java.util.NoSuchElementException;

public class paper2 {
    //默认使用1个AA
    public static long AASetup(int attNum){
        Pairing bp = PairingFactory.getPairing("a.properties");//
        long start = System.currentTimeMillis();
        Element g = bp.getG1().newRandomElement().getImmutable();//
        for(int i = 0 ;i<attNum;i++)
        {
            Element ax = bp.getZr().newRandomElement().getImmutable();//
            Element yx = bp.getZr().newRandomElement().getImmutable();//
            Element vx = bp.getZr().newRandomElement().getImmutable();//
            Element egg_axvx = bp.pairing(g,g).powZn(ax).powZn(vx);
            Element g_yx = g.powZn(yx);
        }

        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element g_beta = g.powZn(beta);
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long KeyGen(int attNum) throws Exception{
        Pairing bp = PairingFactory.getPairing("a.properties");//
        String gid= "1024";
        Element g = bp.getG1().newRandomElement().getImmutable();//
        long start = System.currentTimeMillis();
        Element ax = bp.getZr().newRandomElement().getImmutable();//
        Element yx = bp.getZr().newRandomElement().getImmutable();//
        Element vx = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//

        for(int i = 0 ;i<attNum;i++){

            byte[] attHash = Tool.sha1(gid);
            Element hgid = bp.getG1().newElementFromHash(attHash, 0, attHash.length).getImmutable();
            byte[] attHash1 = Tool.sha1(Integer.toString(attNum));
            Element hx = bp.getG1().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();
            Element D1x =g.powZn(ax).powZn(vx).mul(hgid.powZn(yx)) ;
            Element D2x = hx.powZn(beta);
        }
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long Encrypt(int attNum)throws Exception{
        Pairing bp = PairingFactory.getPairing("a.properties");//
        String gid= "1024";
        Element g = bp.getG1().newRandomElement().getImmutable();//

        Element ax = bp.getZr().newRandomElement().getImmutable();//
        Element yx = bp.getZr().newRandomElement().getImmutable();//
        Element vx = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element gbeta = g.powZn(beta).getImmutable();//
        Element message = bp.getGT().newZeroElement().getImmutable();//


        Element a = bp.getZr().newRandomElement().getImmutable();//
        Element s = bp.getZr().newRandomElement().getImmutable();//
        Element zero = bp.getZr().newZeroElement().getImmutable();//
        long start = System.currentTimeMillis();
        Element C0 =message.mul(bp.pairing(g,g).powZn(s)).getImmutable();
        Element h =g.powZn(a).getImmutable();

        for(int i = 0 ;i<attNum;i++ ){
            Element ui = bp.getZr().newRandomElement().getImmutable();//
            Element sigmai = bp.getZr().newRandomElement().getImmutable();//
            Element phi = bp.getZr().newRandomElement().getImmutable();//
            byte[] attHash1 = Tool.sha1(Integer.toString(attNum));
            Element hx = bp.getG1().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();
            Element sy = bp.pairing(gbeta.powZn(a),hx).getImmutable();
            Element ri = bp.getZr().newRandomElement().getImmutable();//
            Element ti = bp.getZr().newRandomElement().getImmutable();//
            Element Ci1 = bp.pairing(g,g).powZn(ui).mul(bp.pairing(g,g).powZn(vx.mul(ax).mul(sigmai))).getImmutable();
            Element Ci2 = g.powZn(sigmai).getImmutable();
            Element Ci3 = g.powZn(sigmai).powZn(yx).mul(g.powZn(phi)).getImmutable();
        }
        long end = System.currentTimeMillis();
        return end-start;
    }
    public static long Decrypt(int attNum)throws Exception {
        Pairing bp = PairingFactory.getPairing("a.properties");//
        String gid= "1024";
        Element g = bp.getG1().newRandomElement().getImmutable();//
        Element ax = bp.getZr().newRandomElement().getImmutable();//
        Element yx = bp.getZr().newRandomElement().getImmutable();//
        Element vx = bp.getZr().newRandomElement().getImmutable();//
        Element beta = bp.getZr().newRandomElement().getImmutable();//
        Element gbeta = g.powZn(beta).getImmutable();//
        Element a = bp.getZr().newRandomElement().getImmutable();//
        Element s = bp.getZr().newRandomElement().getImmutable();//
        Element zero = bp.getZr().newZeroElement().getImmutable();//
        Element message = bp.getGT().newZeroElement().getImmutable();//
        Element C0 =message.mul(bp.pairing(g,g).powZn(s)).getImmutable();
        Element h0 =g.powZn(a).getImmutable();
        Element ui = bp.getZr().newRandomElement().getImmutable();//
        Element sigmai = bp.getZr().newRandomElement().getImmutable();//
        Element phi = bp.getZr().newRandomElement().getImmutable();//
        byte[] attHash1 = Tool.sha1(Integer.toString(1));
        Element hx = bp.getG1().newElementFromHash(attHash1, 0, attHash1.length).getImmutable();

        Element ci = bp.getZr().newRandomElement().getImmutable();//
        Element Ci1 = bp.pairing(g,g).powZn(ui).mul(bp.pairing(g,g).powZn(vx).powZn(ax).powZn(sigmai)).getImmutable();
        Element Ci2 = g.powZn(sigmai).getImmutable();
        Element Ci3 = g.powZn(sigmai).powZn(yx).mul(g.powZn(phi)).getImmutable();
        //密钥
        Element D1x =g.powZn(ax).powZn(vx).mul(hx.powZn(yx)) ;
        Element D2x = hx.powZn(beta);
        Element dec =bp.getGT().newOneElement().getImmutable();

        long start = System.currentTimeMillis();
        for(int i = 0 ;i<attNum;i++ ){
            Element s_ = bp.pairing(h0,D2x).getImmutable();
            Element e = Ci1.mul(bp.pairing(hx,Ci3)).getImmutable();
            Element f = bp.pairing(D1x,Ci2).getImmutable();
            dec= dec.mul(e.div(f)).powZn(ci);
        }
        Element msg = C0.div(dec);
        long end = System.currentTimeMillis();
        return end-start;
    }

}

